/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cpproject1;

/**
 *
 * @author Owner
 */
import java.awt.*;
import java.util.EventObject;
import javax.swing.*;
import java.util.Random;

/**
 * 
 * @author The Dark Lord
 */
public class DisplayUI extends JPanel implements Runnable, UpdateUIEventListener {

    private int size;
    private int numberOfPlayers;
    JPanel MainMazePanel;
    JPanel CommentsPanel;
    JLabel[][] labelArray;
    JLabel commentLabel, timeLabel;
    private Maze maze;
    private MazeCellType mazeCellsOnDisplay[][];
    //int players = 10;
    GridLayout gridLayout;
    static JFrame f;
    static int flagStatus;
    
    //UpdateUIEventListener interface
    /**
     * 
     * @param ob
     */
    @Override
    public void updateUI(EventObject ob) {
        UIUpdaterThread uiUpdater = this.new UIUpdaterThread();
        SwingUtilities.invokeLater(uiUpdater);
    }

    //InnerClass
    class UIUpdaterThread implements Runnable {

        @Override
        public void run() {
            setIcons();
        }
    }

    //No UI initialization done here
    /**
     * 
     * @param size
     * @param numberOfPlayers
     */
    public DisplayUI(int size, int numberOfPlayers) {
        this.size = size;
        this.numberOfPlayers = numberOfPlayers;
        this.mazeCellsOnDisplay = new MazeCellType[this.size][this.size];
        this.maze = new Maze(this.size, this.numberOfPlayers);
    }

    private synchronized void setIcons() {
        MazeCellType[][] currentState = this.maze.getDungeon();
        
        if (flagStatus != maze.getFlagStatus())
        {
            flagStatus = maze.getFlagStatus();
            switch(flagStatus)
            {
                case 1:         // Flag Captured
                    this.commentLabel.setText("Flag Captured !!!");
                    timeLabel.setForeground(Color.GREEN);
                    break;
                case 2:         // Flag Player Changed
                    this.commentLabel.setText("Flag Player Changed !!!");
                    break;
                case 3:         // We Have a Winner
                    this.commentLabel.setText("We have a Winner !!!");
                    break;
                case 4:         // Maze Reset
                    this.commentLabel.setText("Maze Reset");
                    timeLabel.setForeground(Color.red);
                    break;
            }
        }
        
        if (maze.getElapsedTime() != null)
        {
            timeLabel.setText(maze.getElapsedTime().toString());
        }
        else
            timeLabel.setText("0");
        
        Boolean isChangeNeeded = false;
        for (int i = 0; i < this.size; i++) {
            for (int j = 0; j < this.size; j++) {
                if (currentState[i][j] != this.mazeCellsOnDisplay[i][j]) {
                    isChangeNeeded = true;
                    break;
                }
            }
            if (isChangeNeeded) {
                break;
            }
        }
        if (!isChangeNeeded) {
            return;
        }
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (this.mazeCellsOnDisplay[i][j] == currentState[i][j]) {
                    continue;
                }
                this.mazeCellsOnDisplay[i][j] = currentState[i][j];
                switch (mazeCellsOnDisplay[i][j]) {
                    case Path:	//path
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/path.gif")));
                        break;
                    case Wall: //wall
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/wall.gif")));
                        break;
                    case Flag: // flag
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/flag.gif")));
                        break;
                    case Player: // player
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/knight.gif")));
                        break;
                    case ZombiePlayer: // zombie
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/zombie.gif")));
                        break;
                    case FlagPlayer: // player with flag
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/knightflag.gif")));
                        break;
                    case FlagZombiePlayer: // zombie with flag
                        this.labelArray[i][j].setIcon(new ImageIcon(DisplayUI.class.getResource("Images/zombieflag.gif")));
                        break;
                }
            }
        }
        
    }

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        DisplayUI s = new DisplayUI(17, 10);
        SwingUtilities.invokeLater(s);
    }

    /**
     * 
     */
    public void createMaze() {
        // generate walls randomly (not a mazeCellsOnDisplay)
        Random randomGenerator = new Random();
        int x, y;

        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (randomGenerator.nextInt(2) == 1) {
                    mazeCellsOnDisplay[i][j] = MazeCellType.Wall;			// wall
                } else {
                    mazeCellsOnDisplay[i][j] = MazeCellType.Path;			// path
                }
            }
        }

        while (true) {
            x = randomGenerator.nextInt(size);
            y = randomGenerator.nextInt(size);
            if (mazeCellsOnDisplay[x][y] == MazeCellType.Path) {
                mazeCellsOnDisplay[x][y] = MazeCellType.Flag;				// flag
                break;
            }
        }

        for (int i = 0; i < this.numberOfPlayers - 2; i++) {
            while (true) {
                x = randomGenerator.nextInt(size);
                y = randomGenerator.nextInt(size);
                if (mazeCellsOnDisplay[x][y] == MazeCellType.Path) {
                    mazeCellsOnDisplay[x][y] = MazeCellType.Player;			//normal players
                    break;
                }
            }
        }

        while (true) {
            x = randomGenerator.nextInt(size);
            y = randomGenerator.nextInt(size);
            if (mazeCellsOnDisplay[x][y] == MazeCellType.Path) {
                mazeCellsOnDisplay[x][y] = MazeCellType.ZombiePlayer;				// Zombie
                break;
            }
        }

        while (true) {
            x = randomGenerator.nextInt(size);
            y = randomGenerator.nextInt(size);
            if (mazeCellsOnDisplay[x][y] == MazeCellType.Path) {
                mazeCellsOnDisplay[x][y] = MazeCellType.FlagPlayer;				// Player With Flag
                break;
            }
        }

        while (true) {
            x = randomGenerator.nextInt(size);
            y = randomGenerator.nextInt(size);
            if (mazeCellsOnDisplay[x][y] == MazeCellType.Path) {
                mazeCellsOnDisplay[x][y] = MazeCellType.FlagZombiePlayer;				// Zombie With Flag
                break;
            }
        }
    }

    private MazeCellType getCellType(int number) {
        for (MazeCellType mct : MazeCellType.values()) {
            if (number == mct.ordinal()) {
                return mct;
            }
        }
        return null;
    }

    @Override
    public void run() {
        //initializing mainFrame
        //System.out.println ("is this dispatcher thread: " + SwingUtilities.isEventDispatchThread());
        f = new JFrame("Knight Riders");
        f.setBounds(300, 0, 600, 630);
        //initializing ThePanel
        this.MainMazePanel = new JPanel();
        this.CommentsPanel = new JPanel();
        this.MainMazePanel.setLayout(new GridLayout(this.size, this.size));
        this.CommentsPanel.setLayout(new GridLayout(2,1));
        this.labelArray = new JLabel[this.size][this.size];
        for (int i = 0; i < this.size; i++) {
            for (int j = 0; j < this.size; j++) {
                this.labelArray[i][j] = new JLabel(new ImageIcon(DisplayUI.class.getResource("Images/wall.gif")));
                this.MainMazePanel.add(this.labelArray[i][j]);
            }
        }
        
        commentLabel = new JLabel("Game Started !!!");
        timeLabel = new JLabel();
        timeLabel.setForeground(Color.red);
        this.CommentsPanel.add(commentLabel);
        this.CommentsPanel.add(timeLabel);
        
        createMaze();
        setIcons();
        this.add(this.MainMazePanel);
        this.add(this.CommentsPanel);
        f.add(this);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        f.show();
        f.setVisible(true);
        this.maze.subscribeToUIEvents(this);
        this.maze.startGame();
    }
}
